package orchestration.android;

import java.util.HashMap;

import orchestration.android.execution.AndroidLockableExecution;
import orchestration.android.execution.IOrchestrationCache;
import orchestration.businessprocess.execution.BPExecution;
import orchestration.businessprocess.model.BusinessProcessModel;
import orchestration.persistence.OrchestratorAuthority;
import android.app.Application;
import android.content.UriMatcher;
import android.net.Uri;
/**
 * Class used to manage application's global state. In this case, we have to manage caches and a counter for notifications
 * @author <a href="mailto:car.ferrarini@gmail.com">Carlo Ferrarini</a>
 *
 */
public class OrchestratorApp extends Application implements IOrchestrationCache {
	/**
	 * cache for {@link BusinessProcessModel}
	 */
	private HashMap<Uri, BusinessProcessModel> bpmCache;
	/**
	 * cache for {@link BPExecution}
	 */
	private HashMap<Uri, AndroidLockableExecution> executionCache;
	/**
	 * notification counter
	 */
	private int notificationCount=0;
	private static final UriMatcher sUriMatcher;
	private static final int PROCESS_ID=1;
	private static final int EXECUTION_ID=2;
	
	@Override
	public void onCreate() {
		super.onCreate();
		this.bpmCache= new HashMap<Uri, BusinessProcessModel>();
		this.executionCache= new HashMap<Uri, AndroidLockableExecution>();
	}
	/**
	 * clear caches in case of low memory
	 */
	@Override
	public void onLowMemory() {
		super.onLowMemory();
		bpmCache.clear();
		executionCache.clear();
	}
	
	/* (non-Javadoc)
	 * @see orchestration.android.IBpmCache#addBPM(android.net.Uri, orchestration.businessprocess.model.BusinessProcessModel)
	 */
	public void addBPM(Uri procUri,BusinessProcessModel bpm){
		bpmCache.put(procUri, bpm);
	}
	/* (non-Javadoc)
	 * @see orchestration.android.IBpmCache#getBpm(android.net.Uri)
	 */
	public BusinessProcessModel getBpm(Uri procUri){
		return bpmCache.get(procUri);
	}
	/**
	 * @param uri the uri to match
	 * @return true if one of the caches contains a key that is equal to the given Uri
	 */
	@Override
	public boolean contains(Uri uri) {
		switch(sUriMatcher.match(uri)){
		case PROCESS_ID : return bpmCache.containsKey(uri);
		case EXECUTION_ID: return executionCache.containsKey(uri);
		default: return false;
		}
	}
	@Override
	public void addLockableExecution(Uri executionUri,
			AndroidLockableExecution ale) {
		executionCache.put(executionUri, ale);
	}
	@Override
	public AndroidLockableExecution getLockableExecution(Uri executionUri) {
		return executionCache.get(executionUri);
	}
	/**
	 * 
	 * @return a new notification id that can be used to send a notification
	 */
	public int newNotificationId() {
		return ++notificationCount;
	}

	static {
		sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		sUriMatcher.addURI(OrchestratorAuthority.AUTHORITY, "processes/#", PROCESS_ID);
		sUriMatcher.addURI(OrchestratorAuthority.AUTHORITY, "process_executions/#", EXECUTION_ID);
	}
}
